// SkinableGUIBitmapButton.cpp : implementation file
//

#include "stdafx.h"
#include "SkinableGUIBitmapButton.h"
#include "SkinableGUIBitmapDC.h"

using namespace SkinableGUI;
// CSkinableGUIBitmapButton

IMPLEMENT_DYNAMIC(CSkinableGUIBitmapButton, CSkinableGUIButton)

CSkinableGUIBitmapButton::CSkinableGUIBitmapButton(SkinBitmapButton * pSkinBitmapButton) :
CSkinableGUIButton(pSkinBitmapButton)
, m_pCurImage(NULL)
, m_pSavedBackground(NULL)
, m_pContent(NULL)
{

}

CSkinableGUIBitmapButton::~CSkinableGUIBitmapButton()
{
}


BEGIN_MESSAGE_MAP(CSkinableGUIBitmapButton, CSkinableGUIButton)
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_CONTROL_REFLECT(BN_SETFOCUS, &CSkinableGUIBitmapButton::OnBnSetfocus)
	ON_CONTROL_REFLECT(BN_KILLFOCUS, &CSkinableGUIBitmapButton::OnBnKillfocus)
END_MESSAGE_MAP()



// CSkinableGUIBitmapButton message handlers



void SkinableGUI::CSkinableGUIBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	SkinBitmapButton * pBitmapButton =
		dynamic_cast<SkinBitmapButton *>(m_pSkinButton);

	if (!pBitmapButton->NormalSet)
	{
		CSkinableGUIButton::DrawItem(lpDrawItemStruct);

		return;
	}

	KillTimer(IDT_SKINABLE_BUTTON);

	CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

	CRect rcItem(lpDrawItemStruct->rcItem);

	if (m_pSavedBackground == NULL)
	{
		m_pSavedBackground = new CBitmap();
		m_pSavedBackground->CreateCompatibleBitmap(pDC,
			rcItem.Width(), rcItem.Height());

		CSkinableGUIBitmapDC dc(pDC, m_pSavedBackground);

		dc.BitBlt(0,0,
			rcItem.Width(), rcItem.Height(),
			pDC,
			rcItem.left, rcItem.top,
			SRCCOPY);
	}

	CSkinableGUIBitmapDC savedDC(pDC, m_pSavedBackground);

	if (m_pContent == NULL)
	{
		m_pContent = new CBitmap();
		m_pContent->CreateCompatibleBitmap(pDC,
			rcItem.Width(), rcItem.Height());
	}

	CSkinableGUIBitmapDC contentDC(pDC, m_pContent);

	contentDC.BitBlt(0,0,
		rcItem.Width(), rcItem.Height(),
		&savedDC,
		rcItem.left, rcItem.top,
		SRCCOPY);

	if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED &&
		pBitmapButton->SelectedSet)
	{
		m_pCurImage = &m_SelectedImage;
	}
	else if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED &&
		pBitmapButton->DisabledSet)
	{
		m_pCurImage = &m_DisableImage;
	}
	else if ((lpDrawItemStruct->itemState & ODS_FOCUS) == ODS_FOCUS &&
		pBitmapButton->FocusSet)
	{
		m_pCurImage = &m_FocusImage;
	}
	else
	{
		m_pCurImage = &m_NormalImage;
	}

	DrawButtonImage(&contentDC, 
		m_pCurImage,
		rcItem);

	pDC->BitBlt(rcItem.left, rcItem.top,
		rcItem.Width(), rcItem.Height(),
		&contentDC,
		0,0,
		SRCCOPY);

	SetTimer(IDT_SKINABLE_BUTTON, 150, NULL);
}

BOOL SkinableGUI::CSkinableGUIBitmapButton::PreCreateWindow(CREATESTRUCT& cs)
{
	SkinBitmapButton * pBitmapButton =
		dynamic_cast<SkinBitmapButton *>(m_pSkinButton);

	if (pBitmapButton != NULL && pBitmapButton->NormalSet)
	{
		cs.style |= BS_OWNERDRAW;
	}

	return CSkinableGUIButton::PreCreateWindow(cs);
}

int SkinableGUI::CSkinableGUIBitmapButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CSkinableGUIButton::OnCreate(lpCreateStruct) == -1)
		return -1;

	SkinBitmapButton * pBitmapButton =
		dynamic_cast<SkinBitmapButton *>(m_pSkinButton);

	if (pBitmapButton->NormalSet)
		m_NormalImage.Load(&pBitmapButton->Normal);

	if (pBitmapButton->DisabledSet)
		m_DisableImage.Load(&pBitmapButton->Disabled);

	if (pBitmapButton->FocusSet)
		m_FocusImage.Load(&pBitmapButton->Focus);

	if (pBitmapButton->SelectedSet)
		m_SelectedImage.Load(&pBitmapButton->Selected);

	return 0;
}

void SkinableGUI::CSkinableGUIBitmapButton::OnTimer(UINT_PTR nIDEvent)
{
	static int frame_count = 0;

	if (m_pCurImage != NULL)
	{
		if (m_pCurImage->GetNumFrames() == 1)
			return;

		CDC * pDC = GetDC();

		CRect rcClient;

		GetClientRect(&rcClient);

		if (frame_count >= m_pCurImage->GetNumFrames())
		{
			frame_count = 0;
		}

		DrawButtonImage(pDC,
			m_pCurImage,
			rcClient,
			frame_count);

		ReleaseDC(pDC);

		frame_count++;
	}
	else
	{
		CSkinableGUIButton::OnTimer(nIDEvent);
	}
}

void SkinableGUI::CSkinableGUIBitmapButton::OnSize(UINT nType, int cx, int cy)
{
	CSkinableGUIButton::OnSize(nType, cx, cy);

	if (m_pContent != NULL)
		delete m_pContent;

	m_pContent = NULL;

	if (m_pSavedBackground != NULL)
		delete m_pSavedBackground;

	m_pSavedBackground = NULL;
}

void SkinableGUI::CSkinableGUIBitmapButton::OnDestroy()
{
	CSkinableGUIButton::OnDestroy();

	if (m_pContent != NULL)
		delete m_pContent;

	if (m_pSavedBackground != NULL)
		delete m_pSavedBackground;
}

BOOL SkinableGUI::CSkinableGUIBitmapButton::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}

void SkinableGUI::CSkinableGUIBitmapButton::OnPaint()
{
	CPaintDC dc(this); 	
	
	CDC * pDC = &dc;

	SkinBitmapButton * pBitmapButton =
		dynamic_cast<SkinBitmapButton *>(m_pSkinButton);

	if (!pBitmapButton->NormalSet)
	{
		CSkinableGUIButton::OnPaint();

		return;
	}

	KillTimer(IDT_SKINABLE_BUTTON);

	CRect rcItem;
	GetClientRect(rcItem);

	if (m_pSavedBackground == NULL)
	{
		m_pSavedBackground = new CBitmap();
		m_pSavedBackground->CreateCompatibleBitmap(pDC,
			rcItem.Width(), rcItem.Height());

		CSkinableGUIBitmapDC dc(pDC, m_pSavedBackground);

		dc.BitBlt(0,0,
			rcItem.Width(), rcItem.Height(),
			pDC,
			rcItem.left, rcItem.top,
			SRCCOPY);
	}

	CSkinableGUIBitmapDC savedDC(pDC, m_pSavedBackground);

	if (m_pContent == NULL)
	{
		m_pContent = new CBitmap();
		m_pContent->CreateCompatibleBitmap(pDC,
			rcItem.Width(), rcItem.Height());
	}

	CSkinableGUIBitmapDC contentDC(pDC, m_pContent);

	contentDC.BitBlt(0,0,
		rcItem.Width(), rcItem.Height(),
		&savedDC,
		rcItem.left, rcItem.top,
		SRCCOPY);

	if ((GetState() & 0x0004) == 0x0004 &&
		pBitmapButton->SelectedSet)
	{
		m_pCurImage = &m_SelectedImage;
	}
	else if (!IsWindowEnabled() &&
		pBitmapButton->DisabledSet)
	{
		m_pCurImage = &m_DisableImage;
	}
	else if ((GetState() & 0x0008) == 0x0008 &&
		pBitmapButton->FocusSet)
	{
		m_pCurImage = &m_FocusImage;
	}
	else
	{
		m_pCurImage = &m_NormalImage;
	}

	DrawButtonImage(&contentDC, 
		m_pCurImage,
		rcItem);

	pDC->BitBlt(rcItem.left, rcItem.top,
		rcItem.Width(), rcItem.Height(),
		&contentDC,
		0,0,
		SRCCOPY);

	SetTimer(IDT_SKINABLE_BUTTON, 150, NULL);
}

void SkinableGUI::CSkinableGUIBitmapButton::OnBnSetfocus()
{
	// TODO: Add your control notification handler code here
}

void SkinableGUI::CSkinableGUIBitmapButton::OnBnKillfocus()
{
	// TODO: Add your control notification handler code here
}
